package com.dx.financehy.modules.file.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dx.financehy.exception.BadRequestException;
import com.dx.financehy.modules.file.dao.FileBizMapper;
import com.dx.financehy.modules.file.dao.FileMapper;
import com.dx.financehy.modules.file.domain.FileBizEntity;
import com.dx.financehy.modules.file.domain.FileEntity;
import com.dx.financehy.modules.file.domain.dto.DeleteFileDTO;
import com.dx.financehy.modules.file.domain.dto.FileBizDTO;
import com.dx.financehy.modules.file.domain.vo.FileRetVO;
import com.dx.financehy.modules.file.domain.vo.FileVO;
import com.dx.financehy.modules.file.service.FileBizService;
import com.dx.financehy.modules.file.service.FileService;
import com.dx.financehy.utils.FileVerifyUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * <pre>
 * @描述：阿里云oss存储文件
 * @作者：CLD
 * @创建时间：2022-04-18 21:26
 * </pre>
 **/
@RequiredArgsConstructor
@Service
@Slf4j
public class FileServiceImpl extends ServiceImpl<FileMapper, FileEntity> implements FileService {

    private final FileBizService fileBizService;
    private final FileMapper fileMapper;
    private final FileBizMapper fileBizMapper;

    @Override
    public List<FileBizEntity> selectFileBiz(String applyId) {
        return baseMapper.selectFileBiz(applyId);
    }


    @Override
    public boolean saveFileBiz(FileBizEntity fileBizEntity) {
        return fileBizService.save(fileBizEntity);
    }

    @Override
    public List<FileVO> selectFileByBizId(String bizId) {
        return baseMapper.selectFileByBizId(bizId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public FileVO newUploadFile(MultipartFile file, File filePath) throws Exception {
        String orgName = file.getOriginalFilename();
        InputStream inputStream = file.getInputStream();

        boolean ok = FileVerifyUtil.suffixVerify(orgName, inputStream);
        if (!ok) {
            throw new BadRequestException("仅支持上传.jpg.jpeg.png.bmp.pdf类型文件");
        }

        //执行“文件上传”的方法
        file.transferTo(filePath);

        FileEntity fileEntity = new FileEntity();
        fileEntity.setOrgName(orgName);
        fileEntity.setFileName(fileEntity.getOrgName());
        fileEntity.setSize(file.getSize());
        fileEntity.setMimeType(orgName.substring(orgName.lastIndexOf(".") + 1).toLowerCase());
        fileEntity.setPath(filePath.getPath());
        if (baseMapper.insert(fileEntity) > 0) {
            FileVO fileVO = new FileVO();
            fileVO.setId(fileEntity.getId());
            fileVO.setPath(filePath.getPath());
            fileVO.setFileName(fileEntity.getOrgName());
            fileVO.setOrgName(fileEntity.getOrgName());
            return fileVO;
        }
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateFileBizRef(FileBizDTO fileBizDTO) throws Exception {
        // 先删除原有的，再插入新的
        List<FileRetVO> fileList = baseMapper.selectFileInfoByBizId(fileBizDTO.getBizId());
        if (CollectionUtil.isNotEmpty(fileList)) {
            List<String> fileIdList = new ArrayList<>();
            for (FileRetVO fileDO : fileList) {
                fileIdList.add(fileDO.getId());
                // 先删除文件
                String path = fileDO.getPath();
                File file = new File(path);

                if (file != null || file.exists()) {
                    try {
                        file.delete();
                    } catch (Exception e) {
                        throw new RuntimeException("Failed to delete file: " + path, e);
                    }

                }
            }
            // 删除文件&关联记录
            if (fileIdList.size() > 0) {
                //baseMapper.deleteBatchIds(fileIdList);
                baseMapper.deleteById(fileBizDTO.getBizId());
                QueryWrapper<FileBizEntity> wrapper = new QueryWrapper<>();
                wrapper.eq("biz_id", fileBizDTO.getBizId());
                wrapper.eq("file_id", fileIdList.get(0));
                fileBizMapper.delete(wrapper);
            }
        }
        // 重新进行批量关联插入
        FileBizEntity fileBizDO = new FileBizEntity();
        BeanUtils.copyProperties(fileBizDTO, fileBizDO);
        return baseMapper.insertFileBiz(fileBizDO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteFile(DeleteFileDTO dto) throws Exception {
        if (baseMapper.deleteById(dto.getId()) > 0) {

            File file = new File(dto.getFilePath());

            if (file == null || !file.exists()) {
                return false;
            }
            try {
                file.delete();
            } catch (Exception e) {
                throw new RuntimeException("Failed to delete file: " + dto.getFilePath(), e);
            }
            return true;
        }
        return false;
    }
}
